home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / util / cli / iuw_clitools.lha / src / tee.c < prev   
C/C++ Source or Header  |  1995-09-05  |  4KB  |  132 lines

  1. /* tee - T-intersection in a pipe (similar to Un*x' tee)
  2.  *
  3.  * Copyright (C) 1995 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose and without fee is hereby granted, provided
  7.  * that the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation.  This software is provided "as is" without express or
  10.  * implied warranty.
  11.  *
  12.  * V1.0: 10/Feb/95: first version
  13.  * V1.1: 12/Feb/95: added IsInteractive() check
  14.  */
  15. #define THIS_PROGRAM    "tee"
  16. #define THIS_VERSION    "1.1"
  17.  
  18. #include <exec/types.h>
  19. #include <exec/libraries.h>
  20. #include <exec/memory.h>
  21. #include <dos/dos.h>
  22. #include <dos/rdargs.h>
  23. #include <dos/dosasl.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #define SysBase_DECLARED
  28. #include <proto/exec.h>
  29. #include <proto/dos.h>
  30.  
  31. extern struct Library *SysBase;
  32.  
  33. #define DEFAULT_BUFFERS     100     /* same as C:copy */
  34. #define BUFFER_BLOCK_SIZE   512
  35.  
  36.  
  37. static const char amiga_version[] = "\0$VER: " THIS_PROGRAM " " THIS_VERSION " (" __COMMODORE_DATE__ ")";
  38.  
  39. const char Template[] = "FILE,APPEND/S,BUF=BUFFER/K/N";
  40. __aligned struct {
  41.     STRPTR  file;
  42.     LONG    append;
  43.     LONG    *bufsiz;
  44. } Args;
  45. const char console[] =  "CONSOLE:";
  46.  
  47.  
  48. void
  49. _main()
  50. {
  51.     __aligned UBYTE smallbuf[BUFFER_BLOCK_SIZE];
  52.     UBYTE *buf = NULL;
  53.     struct RDArgs *rdargs;
  54.     BPTR infh, outfh, teefh;
  55.     LONG r, r2, last = 0, bufsiz = 0, err = 0;
  56.     BOOL conmode;
  57.  
  58.     if( SysBase->lib_Version < 37 ) {
  59.         #define MESSAGE  THIS_PROGRAM " requires AmigaOS 2.04 or higher\n"
  60.         Write(Output(), MESSAGE, sizeof(MESSAGE)-1);
  61.         _exit(RETURN_FAIL);
  62.         #undef MESSAGE
  63.     }
  64.  
  65.     if( rdargs = ReadArgs(Template, (LONG *)&Args, NULL) ) {
  66.         infh = Input(); outfh = Output();
  67.  
  68.         /* some stream devices don't support MODE_READWRITE */
  69.         if( teefh = Open(Args.file ? Args.file : (STRPTR)console, Args.append ? MODE_READWRITE : MODE_NEWFILE) ) {
  70.             if( IsInteractive(teefh) )
  71.                 conmode = TRUE;
  72.             else {
  73.                 conmode = FALSE;
  74.                 if( Args.bufsiz )
  75.                     bufsiz = *(Args.bufsiz);
  76.                 if( bufsiz <= 0 )
  77.                     bufsiz = DEFAULT_BUFFERS;
  78.                 bufsiz *= BUFFER_BLOCK_SIZE;
  79.  
  80.                 while( bufsiz > BUFFER_BLOCK_SIZE && (buf = AllocMem(bufsiz, MEMF_ANY))==NULL )
  81.                     bufsiz >>= 1;
  82.  
  83.                 if( Args.append )
  84.                     if( Seek(teefh, 0, OFFSET_END) < 0 )
  85.                         err = IoErr();
  86.             }
  87.             if( !buf ) {
  88.                 buf = smallbuf;
  89.                 bufsiz = BUFFER_BLOCK_SIZE;
  90.             }
  91.  
  92.             while( !err && (r = Read(infh, buf, bufsiz)) > 0 ) {
  93.                 if( CheckSignal(SIGBREAKF_CTRL_C) )
  94.                     err = ERROR_BREAK;
  95.                 else {
  96.                     if( Write(outfh, buf, r) != r  ||  (r2 = Write(teefh, buf, r)) != r )
  97.                         err = IoErr();
  98.                     if( r2 > 0 )
  99.                         last = r2;
  100.                 }
  101.             }
  102.             if( conmode && last && buf[last-1] != '\n' )
  103.                 FPutC(teefh, '\n');     /* Write(teefh, "\n", 1); */
  104.  
  105.             Close(teefh);
  106.  
  107.             if( buf != smallbuf )
  108.                 FreeMem(buf, bufsiz);
  109.         }
  110.         else    /* could not open tee file */
  111.             err = IoErr();
  112.  
  113.         FreeArgs(rdargs);
  114.     }
  115.     else    /* error in arguments */
  116.         err = IoErr();
  117.  
  118.     if( err ) {
  119.         /* can't use PrintFault() because it prints to stdout */
  120.         if( Fault(err, THIS_PROGRAM, smallbuf, BUFFER_BLOCK_SIZE) ) {
  121.             if( outfh = Open(console, MODE_READWRITE) ) {
  122.                 FPuts(outfh, smallbuf);
  123.                 FPutC(outfh, '\n');
  124.                 Close(outfh);
  125.             }
  126.         }
  127.         SetIoErr(err);  /* restore for 'why' command */
  128.     }
  129.     _exit(err ? RETURN_ERROR : RETURN_OK);
  130. }
  131.  
  132.